package com.mobileClientKernel.android.serviceManager.network;

import android.content.Context;
import android.support.annotation.NonNull;

import com.mobileClientKernel.android.commonLayer.JJLog;
import com.mobileClientKernel.android.serviceManager.servicefactory.JJServiceFactory;

import org.json.JSONObject;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

/**
 * Created by hamilyjing on 4/9/16.
 */
public class JJBaseRequest {

    private Context context;

    // request
    private long connectTimeoutMilliSecond = 30000;
    private long readTimeoutMilliSecond = 30000;
    private long writeTimeoutMilliSecond = 30000;
    private boolean isRetryOnConnectionFailure = true;
    private JJBaseRequestMethod requestMethod = JJBaseRequestMethod.Post;
    private Map<String, String> requestHeader = new HashMap<>();

    boolean isSslVerify = false;
    SSLSocketFactory sslSocketFactory;
    X509TrustManager trustManager;

    private IJJResponseCallBack responseCallBack;

    // response
    private Integer responseCode;
    private String responseString;
    private JJRequestError error;
    private Map<String, String> responseHeaders;

    private JSONObject otherInfo;

    public JJBaseRequest()
    {
    }

    public boolean isUseCDN()
    {
        return false;
    }

    public String cdnUrl()
    {
        return "";
    }

    public String hostUrl()
    {
        return "";
    }

    public String pathUrl()
    {
        return "";
    }

    public Map<String, String> requestArgument()
    {
        return null;
    }

    public void requestCompleteFilter()
    {
    }

    public void requestFailedFilter()
    {
    }

    public void start()
    {
        JJNetworkAgent.getInstance().addRequest(this);
    }

    public void startWithCallBack(IJJResponseCallBack callBack)
    {
        this.responseCallBack = callBack;
        start();
    }

    public void stop()
    {
        JJNetworkAgent.getInstance().cancelRequest(this);
    }

    public String buildRequestUrl()
    {
        String detailUrl = pathUrl();
        if (detailUrl.startsWith("http"))
        {
            return detailUrl;
        }

        String baseUrl;
        if (isUseCDN())
        {
            baseUrl = cdnUrl();
        }
        else
        {
            baseUrl = hostUrl();
        }

        String url = baseUrl + detailUrl;
        return url;
    }

    public HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        return hostnameVerifier;
    }

    /// get and set

    public JJBaseRequestMethod getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(JJBaseRequestMethod requestMethod) {
        this.requestMethod = requestMethod;
    }

    public IJJResponseCallBack getResponseCallBack() {
        return responseCallBack;
    }

    public void setResponseCallBack(IJJResponseCallBack responseCallBack) {
        this.responseCallBack = responseCallBack;
    }

    public Integer getResponseCode() {
        return responseCode;
    }

    public void setResponseCode(Integer responseCode) {
        this.responseCode = responseCode;
    }

    public String getResponseString() {
        return responseString;
    }

    public void setResponseString(String responseString) {
        this.responseString = responseString;
    }

    public Context getContext() {
        if (context != null) {
            return context;
        }
        Context serviceFactoryContext = JJServiceFactory.getInstance().getContext();
        return serviceFactoryContext;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public JJRequestError getError() {
        return error;
    }

    public void setError(JJRequestError error) {
        this.error = error;
    }

    public JSONObject getOtherInfo() {
        return otherInfo;
    }

    public void setOtherInfo(JSONObject otherInfo) {
        this.otherInfo = otherInfo;
    }

    public void setResponseHeaders(Map<String, String> responseHeaders) {
        this.responseHeaders = responseHeaders;
    }

    public long getConnectTimeoutMilliSecond() {
        return connectTimeoutMilliSecond;
    }

    public void setConnectTimeoutMilliSecond(long connectTimeoutMilliSecond) {
        this.connectTimeoutMilliSecond = connectTimeoutMilliSecond;
    }

    public long getReadTimeoutMilliSecond() {
        return readTimeoutMilliSecond;
    }

    public void setReadTimeoutMilliSecond(long readTimeoutMilliSecond) {
        this.readTimeoutMilliSecond = readTimeoutMilliSecond;
    }

    public long getWriteTimeoutMilliSecond() {
        return writeTimeoutMilliSecond;
    }

    public void setWriteTimeoutMilliSecond(long writeTimeoutMilliSecond) {
        this.writeTimeoutMilliSecond = writeTimeoutMilliSecond;
    }

    public Map<String, String> getResponseHeaders() {
        return responseHeaders;
    }

    public boolean isRetryOnConnectionFailure() {
        return isRetryOnConnectionFailure;
    }

    public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
        isRetryOnConnectionFailure = retryOnConnectionFailure;
    }

    public Map<String, String> getRequestHeader() {
        return requestHeader;
    }

    public void setRequestHeader(Map<String, String> requestHeader) {
        this.requestHeader = requestHeader;
    }

    public boolean isSslVerify() {
        return isSslVerify;
    }

    public void setSslVerify(boolean sslVerify) {
        isSslVerify = sslVerify;
    }

    public SSLSocketFactory getSslSocketFactory() {
        return sslSocketFactory;
    }

    public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
        this.sslSocketFactory = sslSocketFactory;
    }

    public X509TrustManager getTrustManager() {
        return trustManager;
    }

    public void setTrustManager(X509TrustManager trustManager) {
        this.trustManager = trustManager;
    }
}
